#ifndef ROI_H
#define ROI_H

#include <QDebug>
#include <QGraphicsItem>
#include <QObject>
#include <QtMath>
#include <QRect>
#include <QMenu>
#include <QCursor>
#include <QPainter>
#include <QTransform>
#include <QVector2D>
#include <QVector3D>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QContextMenuEvent>
#include <QGraphicsSceneContextMenuEvent>

#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;

#define PI 3.14159265358979

static Mat QImageTocvMat(const QImage& image);

enum ROIShape
{
    RECTANGE = 0,
    ROTATERECTANGE,
    ELLIPSE,
    CIRCLE,
    POLYGON
};

class ROI : public QObject, public QGraphicsItem
{
    Q_OBJECT
public:
    ROI(QGraphicsItem* parent = nullptr);

    virtual QRectF boundingRect() const override;
    virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) = 0;
    virtual ROIShape Type() = 0;

    static void setMask(const QList<QGraphicsItem*> &items, Mat& mask);  // 设置掩码矩阵
    virtual void getPolygon(QPolygonF&){}
    QRectF getBoundingRect();

protected:
    void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override;
    void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override;
    void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override;

signals:
    void upROIMask();           // 更新掩码矩阵
    void delROIItem();          // 删除ROI对象

protected:
    QRectF m_rect;
    QRectF m_SRect;         // 较小的外围矩形
    QPointF m_pos;          // 本地开始坐标
    bool m_isResizing;      // 大小
    bool m_isMoving;        // 移动
    bool m_isRotating;      // 旋转
    bool m_isSelected;      // 被选中
    ROIShape m_shape;       // 形状
};

// --------------------------  矩形  ---------------------------
class Rectangle: public ROI
{
public:
    Rectangle();
    Rectangle(QRectF&);
    virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
    ROIShape Type() override {return m_shape;}

    // bool isRotate();
    void setboundingRect(QRectF& rectf);

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
    void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;

protected:
    QRectF m_scaleRect1;        // 八个功能点
    QRectF m_scaleRect2;
    QRectF m_scaleRect3;
    QRectF m_scaleRect4;
    QRectF m_scaleRect5;
    QRectF m_scaleRect6;
    QRectF m_scaleRect7;
    QRectF m_scaleRect8;
    bool m_s1,m_s2,m_s3,m_s4,m_s5,m_s6,m_s7,m_s8;       // 功能点的标志位
};


// ----------------------  旋转矩形  ----------------------------
class RotateRectangle: public Rectangle
{
public:
    RotateRectangle();
    RotateRectangle(QRectF&);
    virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
    ROIShape Type() override {return m_shape;}
    void setboundingRect(QRectF& rectf, QTransform& transform);
    QTransform &getQTransform();

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
    void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;

private:
    qreal m_initRotation = 0;       // 旋转角度
    QTransform m_transform;         // 变换矩阵
};


// -------------------------  椭圆  ---------------------------
class Ellipse: public ROI
{
public:
    Ellipse();
    Ellipse(QRectF&);
    virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
    ROIShape Type() override {return m_shape;}
    void setboundingRect(QRectF& rectf);

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
    void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;

protected:
    QRectF m_pointUp;
    QRectF m_pointLeft;
    QRectF m_pointDown;
    QRectF m_pointRight;
    bool m_up, m_down, m_left, m_right;
};


// -------------------------  圆  ---------------------------
class Circle: public Ellipse
{
public:
    Circle();
    Circle(QRectF&);
    ROIShape Type() override {return m_shape;}
protected:
    void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override;
};


// -------------------------  多边形  ---------------------------
class Polygon: public ROI
{
    Q_OBJECT
public:
    Polygon(const QPolygonF&);
    QRectF boundingRect() const override;
    virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
    ROIShape Type() override {return m_shape;};
    QPainterPath shape() const override;
    void getPolygon(QPolygonF& polygon) override{polygon = m_polygon;}
    void setboundingRect(QRectF& rectf) {}
    void setContextMenuEnabled(bool enable);

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
    void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
    void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override;  // 重写右键菜单

public slots:
    void delROIItem(bool check);

private:
    QPolygonF m_polygon;        // 多边形点集合
    int m_index;                // 多边形点顺序下标
    bool m_contextMenuEnable;   // 右击菜单许可
};

#endif // ROI_H
